#include "forco_os.h"

OS_TCB      *OSTCBCurPtr; 
OS_TCB      *OSTCBHighRdyPtr;
extern OS_RDY_LIST  OSRdyList;
extern CPU_UINT32   OSTickCtr;
OS_TCB      IDLETaskTCB;
CPU_UINT8   IDLETaskStk[512];
CPU_UINT32  OSIdleTaskCtr=0;
CPU_UINT32  OSCurPrio = 0;
CPU_UINT32  OSCurPrioHight =0;

void OSInit(void)
{
    OSTickCtr            = 0;
    OSTCBCurPtr          = (OS_TCB*)0;
    OSTCBHighRdyPtr      = (OS_TCB*)0;
    OS_TickListInit();
    OS_PrioInit();
    OS_RdyListInit();    
}


//任务切换函数
void OSSched(void)
{
    //进入临界区
    CPU_SR_ALLOC();
    CPU_INT_DIS();
    //找高优先级
    OSCurPrioHight = OS_PrioGetHighest();
    //Forco_Printf("OSCurPrioHight=%d\r\n",OSCurPrioHight);
    //获取优先级,当前优先级和最高优先级不匹配切换
    /*
    if(OSCurPrioHight != OSCurPrio){ 
         OSTCBHighRdyPtr = OSRdyList.RdylistHead;  
         OSCurPrio = OSCurPrioHight;
    }
    */
    OSTCBHighRdyPtr = OSRdyList.RdylistHead;  
    //最高优先级等于就绪表的第一个
    CPU_INT_EN();
    //触发pend中断
    OS_TASK_SW();
}

//初始化任务控制块
void OS_TaskTCBInit(OS_TCB *p_tcb)
{
    //将全部变量清空
    p_tcb->stkptr           = (CPU_UINT32*)0;
    p_tcb->taskname         = (CPU_INT8*)0;
    p_tcb->taskprio         = (CPU_UINT32)0;
    p_tcb->TickCtrMatch     = (CPU_UINT32)0;
    p_tcb->TickRemain       = (CPU_UINT32)0;
    p_tcb->TCBTickNextPtr   = (OS_TCB*)0;
    p_tcb->TCBTickPrevPtr   = (OS_TCB*)0;
    p_tcb->TickSpokePtr     = (OS_TICK_LIST*)0;
    p_tcb->TaskState        = OS_TASK_STATE_RDY;
}

//任务堆栈初始化
CPU_UINT32 *OS_TaskStkInit(TASK_FUNCTION taskfun,void *p_arg,CPU_UINT32 *p_stk_base,CPU_UINT32 stk_size)
{
   CPU_UINT32   *p_stktop;
   //stm32的栈时向下生长
   //获取栈顶
   p_stktop         =   &p_stk_base[stk_size];
   //将堆栈8-bytes对齐
   //p_stktop         =  (CPU_UINT32*)((CPU_UINT32)(p_stktop) & 0xFFFFFFF8u);
   //异常发生时自动保存的寄存器
	//xpsr 的第24位写1防止产生 INVSTATE 异常
	*--p_stktop =  (CPU_UINT32)0x01000000u;  //xpsr 寄存器
	*--p_stktop =  (CPU_UINT32)taskfun;       //R15(PC)任务的入口地址
	*--p_stktop =  (CPU_UINT32)0x14141414u;  //r14(LR)
    *--p_stktop =  (CPU_UINT32)0x12121212u;  //r12
    *--p_stktop =  (CPU_UINT32)0x03030303u;  //r3
    *--p_stktop =  (CPU_UINT32)0x02020202u;  //r2
    *--p_stktop =  (CPU_UINT32)0x01010101u;  //r1
    *--p_stktop =  (CPU_UINT32)p_arg;        //r0 任务形参

	/*异常需要手动保存的参数*/
    *--p_stktop =  (CPU_UINT32)0x11111111u;  //R11
    *--p_stktop =  (CPU_UINT32)0x10101010u;  //R10
    *--p_stktop =  (CPU_UINT32)0x09090909u;  //R9
	*--p_stktop =  (CPU_UINT32)0x08080808u;  //R8
    *--p_stktop =  (CPU_UINT32)0x07070707u;  //R7
    *--p_stktop =  (CPU_UINT32)0x06060606u;  //R6
    *--p_stktop =  (CPU_UINT32)0x05050505u;  //R5
    *--p_stktop =  (CPU_UINT32)0x04040404u;  //R4
	return p_stktop;
}





//创建任务,暂时不支持内存管理，使用静态放到进行创建
//任务控制块
//创建任务的函数
//任务运行时传入的参数
//任务的名称
//任务的优先级
//任务的堆栈地址
//堆栈大小
//错误码
void OSTaskCreateStatic(OS_TCB* p_tcb,TASK_FUNCTION taskfun,void *p_arg,CPU_INT8 *TaskName,CPU_UINT32 prio,CPU_UINT32 *p_stk_base,CPU_UINT32 stk_size,OS_ERR* err)
{
    CPU_UINT32 *TaskInitRet;
    OS_TaskTCBInit(p_tcb);
    TaskInitRet = OS_TaskStkInit(taskfun,p_arg,p_stk_base,stk_size);
    //防止编译警告
    p_tcb->stkptr = TaskInitRet;
    p_tcb->taskname = TaskName;
    p_tcb->taskprio = prio; 
    //插入就绪表
    OS_RdyListInsert(p_tcb);
    *err = OS_ERR_NONE;
}

//空闲任务
void OS_TaskIDLE(void *arg)
{
 for(;;)
 {
    OSIdleTaskCtr++;
 }
}

/*开始运行系统*/
void OSStartRun(void)
{
  OS_ERR err;
  OSTaskCreateStatic(&IDLETaskTCB,OS_TaskIDLE,NULL,"osidle",OS_SUPORT_MAXTASK-1,(CPU_UINT32*)&IDLETaskStk[0],128,&err);  
  err = err;
  //获取最高优先级
  OSCurPrioHight = OS_PrioGetHighest();
  OSTCBHighRdyPtr = OSRdyList.RdylistHead;
  OSStartHighRdy();
}
